﻿using NHibernate.Cfg;
using NHibernate;
using System.Web;
using System.Reflection;
using log4net;
using Wanet.PublicPortal.Common.Utilities;

namespace Wanet.PublicPortal.Common
{
	/// <summary>
	/// The NHibernate helper class that provides a safe way for opening and closing the Sessions.
	/// Takes care about reading the configuration.
	/// </summary>
	public static class HibernateHelper
	{
		private const string CurrentSessionKey = "nhibernate.current_session";
		private static readonly ISessionFactory sessionFactory;
		private static ILog _log = null;
		private static ISession _session = null;

		/// <summary>
		/// Initializes the <see cref="HibernateHelper"/> class.
		/// </summary>
		static HibernateHelper()
		{
			sessionFactory = new Configuration()
				.Configure(Assembly.GetExecutingAssembly(), "Wanet.PublicPortal.Common.Config.NHibernateConfig.xml")
				.BuildSessionFactory();
			_log = Logging.GetLogger(typeof(HibernateHelper));
		}

		/// <summary>
		/// Gets the current session.
		/// </summary>
		/// <returns></returns>
		public static ISession GetCurrentSession()
		{
			HttpContext context = HttpContext.Current;

			if (context == null)
			{
				if (_session == null)
				{
					_session = sessionFactory.OpenSession();
				}

				return _session;
			}

			ISession currentSession = context.Items[CurrentSessionKey] as ISession;
			
			if (currentSession == null)
			{
				currentSession = sessionFactory.OpenSession();
				context.Items[CurrentSessionKey] = currentSession;
			}
			
			return currentSession;
		}

		/// <summary>
		/// Closes the session.
		/// </summary>
		public static void CloseSession()
		{
			HttpContext context = HttpContext.Current;

			if (context == null)
			{
				if (_session == null)
				{
					return;
				}

				_session.Close();

				return;
			}

			ISession currentSession = context.Items[CurrentSessionKey] as ISession;
			
			if (currentSession == null)
			{
				// No current session
				return;
			}

			currentSession.Close();
			context.Items.Remove(CurrentSessionKey);
		}

		/// <summary>
		/// Closes the session factory.
		/// </summary>
		public static void CloseSessionFactory()
		{
			if (sessionFactory != null)
			{
				sessionFactory.Close();
			}
		}
	}
}
